<script setup lang="ts">
import { ref } from 'vue'
import {
  ElUpload,
  ElInput,
  ElProgress,
  type UploadInstance,
  UploadRawFile,
  UploadProps
} from 'element-plus'
import { Icon } from '@/components/Icon'
import { createImageViewer } from '@/components/ImageViewer'
import { uploadImg } from '@/api/utils/upload'
import { propTypes } from '@/utils/propTypes'

/**
 * 此组件为表单中上传单张图片时的需求封装
 * 默认开启进度条动画
 */
const props = defineProps({
  modelValue: propTypes.string.def('')
})
const emit = defineEmits(['update:modelValue'])
const uploadFile = async (options) => {
  return await uploadImg(options.file)
}
const upload = ref<UploadInstance>()
const fileName = ref(props.modelValue)
// 上传成功时的参数拼接以及修改父组件绑定的value值
const onSuccess = (_response: IResponse) => {
  const url = `https://${_response.data.domain}/${_response.data.file_path}`
  emit('update:modelValue', url)
  fileName.value = _response.data.file_name
}
const onError = (error) => {
  fileName.value = error
}
// 覆盖前一张图片的处理
const handleExceed: UploadProps['onExceed'] = (files) => {
  upload.value!.clearFiles()
  const file = files[0] as UploadRawFile
  upload.value!.handleStart(file)
  upload.value?.submit()
}
// 打开图片预览
const open = () => {
  if (!props.modelValue) return
  createImageViewer({
    urlList: [props.modelValue]
  })
}

// Progress
const showProgress = ref(false)
const progressStatus = ref<any>('')
const percentage = ref(0)
const onChange = (uploadFile) => {
  const percentageNum = {
    ready: 50,
    uploading: 80,
    success: 100,
    fail: 100
  }
  showProgress.value = uploadFile.status !== 'success'
  if (uploadFile.status === 'fail') progressStatus.value = 'exception'
  else progressStatus.value = 'success'
  percentage.value = percentageNum[uploadFile.status]
}
</script>
<template>
  <ElUpload
    ref="upload"
    :httpRequest="uploadFile"
    :onSuccess="onSuccess"
    :onError="onError"
    :onChange="onChange"
    :onExceed="handleExceed"
    :showFileList="false"
    :limit="1"
    class="w-full"
  >
    <ElInput v-model:modelValue="fileName" readonly @click.stop="open" :validate-event="false">
      <template #append>
        <Icon icon="ep:upload" :size="22" />
      </template>
    </ElInput>
    <ElProgress
      :percentage="percentage"
      v-show="showProgress"
      :status="progressStatus"
      :indeterminate="false"
      :show-text="false"
      class="mt-[10px]"
      @click.stop
    />
  </ElUpload>
</template>
<style scoped>
:deep(.el-upload) {
  display: block;
}
</style>
